package GUI;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import Other.Glob;
import database.DatabaseExtension;
import database.MyAddressee;
import database.MyCountry;
import database.MyDestination;
import database.NewTirDataBase;
import enums.DialogType;
import enums.SearchType;

public class Destination extends JFrame {
	// variable for singleton
	private static Destination destinationInstance = null;
	private JPanel contentPane;
	private JTextField tfCode;
	private JTextField tfName;
	// variable that represent this window frame
	private JFrame thisFrame = this;
	// variable to enable and disable the screen
	boolean disable;
	private JTextField tfCountryCode;
	private JTextField tfCountryName;

	private Destination() {
		// set the title
		setTitle("Destination");
		setVisible(true);
		// set resizable
		setResizable(false);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setBounds(100, 100, 708, 325);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		JPanel mainPanel = new JPanel();
		mainPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		JPanel buttonPanel = new JPanel();
		buttonPanel.setBorder(new LineBorder(new Color(0, 0, 0)));
		GroupLayout gl_contentPane = new GroupLayout(contentPane);
		gl_contentPane.setHorizontalGroup(gl_contentPane
				.createParallelGroup(Alignment.LEADING)
				.addComponent(buttonPanel, Alignment.TRAILING,
						GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE,
						Short.MAX_VALUE)
				.addComponent(mainPanel, GroupLayout.DEFAULT_SIZE, 623,
						Short.MAX_VALUE));
		gl_contentPane.setVerticalGroup(gl_contentPane.createParallelGroup(
				Alignment.LEADING).addGroup(
				Alignment.TRAILING,
				gl_contentPane
						.createSequentialGroup()
						.addComponent(mainPanel, GroupLayout.DEFAULT_SIZE, 187,
								Short.MAX_VALUE)
						.addPreferredGap(ComponentPlacement.UNRELATED)
						.addComponent(buttonPanel, GroupLayout.PREFERRED_SIZE,
								GroupLayout.DEFAULT_SIZE,
								GroupLayout.PREFERRED_SIZE).addGap(5)));
		JButton btnSave = new JButton("F4 Save");
		btnSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// Save when button pressed
				try {
					Glob.type = SearchType.DESTINATION;
					saveDialog();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		tfCode = new JTextField();
		tfCode.getInputMap(tfCode.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0), "Save");
		tfCode.getActionMap().put("Save", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				// Save when button pressed
				try {
					Glob.type = SearchType.DESTINATION;
					saveDialog();
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		JButton btnRemove = new JButton("F6 Remove");
		// set up F6 for removing
		btnRemove.getInputMap(btnRemove.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0), "");
		btnRemove.getActionMap().put("", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				// remove item when F6 button pressed
				ScreenHandling.remove(tfCode, SearchType.DESTINATION);
			}
		});
		btnRemove.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// remove item when button pressed
				ScreenHandling.remove(tfCode, SearchType.DESTINATION);

			}
		});
		JButton btnFReset = new JButton("F7 Reset");
		// set up F7 for reset
		btnFReset.getInputMap(btnFReset.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0), "");
		btnFReset.getActionMap().put("", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				// reset field when button pressed
				resetFields();
			}
		});
		btnFReset.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// reset field when button pressed
				resetFields();
			}
		});
		JButton btnEscExit = new JButton("Esc Exit");
		// set up Escape for exit
		btnEscExit.getInputMap(btnEscExit.WHEN_IN_FOCUSED_WINDOW).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "");
		btnEscExit.getActionMap().put("", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				if (disable == false) {
					// escape from the screen
					escape();
				}
			}
		});
		btnEscExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// if the screen is disable it is possible to escape
				if (disable == false) {
					escape();
				}
			}
		});
		GroupLayout gl_buttonPanel = new GroupLayout(buttonPanel);
		gl_buttonPanel.setHorizontalGroup(gl_buttonPanel.createParallelGroup(
				Alignment.TRAILING).addGroup(
				gl_buttonPanel
						.createSequentialGroup()
						.addGap(18)
						.addComponent(btnRemove)
						.addPreferredGap(ComponentPlacement.RELATED, 220,
								Short.MAX_VALUE).addComponent(btnEscExit)
						.addGap(29).addComponent(btnFReset).addGap(34)
						.addComponent(btnSave).addGap(18)));
		gl_buttonPanel.setVerticalGroup(gl_buttonPanel.createParallelGroup(
				Alignment.LEADING)
				.addGroup(
						gl_buttonPanel
								.createSequentialGroup()
								.addGap(21)
								.addGroup(
										gl_buttonPanel
												.createParallelGroup(
														Alignment.BASELINE)
												.addComponent(btnSave)
												.addComponent(btnRemove)
												.addComponent(btnFReset)
												.addComponent(btnEscExit))
								.addContainerGap(38, Short.MAX_VALUE)));
		buttonPanel.setLayout(gl_buttonPanel);
		JLabel codeLabel = new JLabel("Code");
		JLabel lblName = new JLabel("Destination Name");
		// set up F5 for saving only when the text is focused
		tfCode.getInputMap(tfCode.WHEN_FOCUSED).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), "");
		tfCode.getActionMap().put("", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {
				
				Glob.type = SearchType.DESTINATION;
				// when textcode focused and f5 pressed search dialog comes up
				search();
			}
		});
		JButton searchButton = new JButton("F5 Search");
		searchButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {

				Glob.type = SearchType.DESTINATION;
				// when textcode focused and f5 pressed search dialog comes up
				search();
			}
		});
		tfCode.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				// when a number is entered with ENTER
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {

					//ScreenHandling.enterData(tfCode, tfName, tfName, SearchType.DESTINATION);f
					enterData();

				}

			}
		});
		tfCode.setColumns(10);
		tfName = new JTextField();
		tfName.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				// when a number is entered
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {

					tfCountryCode.requestFocus();
				}
			}
		});
		tfName.setColumns(10);

		JLabel lblCountry = new JLabel("Country");

		tfCountryCode = new JTextField();

		tfCountryCode.addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				// when a number is entered
				if (e.getKeyChar() == KeyEvent.VK_ENTER) {

					ScreenHandling.enterData(tfCountryCode, tfCountryName, tfCode, SearchType.COUNTRY);

					// tfCode.requestFocus();
				}
			}
		});

		tfCountryCode.getInputMap(tfCode.WHEN_FOCUSED).put(
				KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), "");
		tfCountryCode.getActionMap().put("", new AbstractAction() {
			public void actionPerformed(ActionEvent e) {

				Glob.type = SearchType.DESTINATIONCOUNTRY;
				// when textcode focused and f5 pressed search dialog comes up
				search();
			}
		});

		tfCountryCode.setColumns(10);

		tfCountryName = new JTextField();
		tfCountryName.setEditable(false);
		tfCountryName.setColumns(10);

		JButton searchButtonCountry = new JButton("F5 Search");
		searchButtonCountry.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {

				Glob.type = SearchType.DESTINATIONCOUNTRY;
				// when textcode focused and f5 pressed search dialog comes up
				search();
			}
		});

		GroupLayout gl_mainPanel = new GroupLayout(mainPanel);
		gl_mainPanel
				.setHorizontalGroup(gl_mainPanel
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_mainPanel
										.createSequentialGroup()
										.addGap(42)
										.addGroup(
												gl_mainPanel
														.createParallelGroup(
																Alignment.LEADING)
														.addComponent(
																codeLabel,
																GroupLayout.PREFERRED_SIZE,
																68,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(lblName)
														.addComponent(
																lblCountry))
										.addPreferredGap(
												ComponentPlacement.UNRELATED)
										.addGroup(
												gl_mainPanel
														.createParallelGroup(
																Alignment.LEADING)
														.addGroup(
																gl_mainPanel
																		.createSequentialGroup()
																		.addComponent(
																				tfCode,
																				GroupLayout.PREFERRED_SIZE,
																				126,
																				GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap(
																				ComponentPlacement.UNRELATED)
																		.addComponent(
																				searchButton))
														.addGroup(
																gl_mainPanel
																		.createSequentialGroup()
																		.addComponent(
																				tfCountryCode,
																				GroupLayout.PREFERRED_SIZE,
																				41,
																				GroupLayout.PREFERRED_SIZE)
																		.addPreferredGap(
																				ComponentPlacement.UNRELATED)
																		.addComponent(
																				tfCountryName,
																				GroupLayout.DEFAULT_SIZE,
																				166,
																				Short.MAX_VALUE))
														.addComponent(tfName))
										.addPreferredGap(
												ComponentPlacement.UNRELATED)
										.addComponent(searchButtonCountry)
										.addGap(169)));
		gl_mainPanel
				.setVerticalGroup(gl_mainPanel
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_mainPanel
										.createSequentialGroup()
										.addGap(37)
										.addGroup(
												gl_mainPanel
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(codeLabel)
														.addComponent(
																tfCode,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(
																searchButton))
										.addGap(18)
										.addGroup(
												gl_mainPanel
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(lblName)
														.addComponent(
																tfName,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addGap(18)
										.addGroup(
												gl_mainPanel
														.createParallelGroup(
																Alignment.BASELINE)
														.addComponent(
																lblCountry)
														.addComponent(
																tfCountryCode,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(
																tfCountryName,
																GroupLayout.PREFERRED_SIZE,
																GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE)
														.addComponent(
																searchButtonCountry))
										.addContainerGap(49, Short.MAX_VALUE)));
		// request focus when object is called
		tfCode.requestFocus(true);
		mainPanel.setLayout(gl_mainPanel);
		contentPane.setLayout(gl_contentPane);
	}

	// singleton
	public static Destination getInstance() {
		if (destinationInstance == null) {
			destinationInstance = new Destination();
		}
		return destinationInstance;
	}

	// initiate data
	public void init(MyDestination destination) {
		tfCode.setText(destination.getDestinationID());
		tfName.setText(destination.getName());
		tfCountryCode.setText(destination.getCodeCountryID());
		tfCountryName.setText(destination.getCountryName());
	}
	
	public void enterData(){
		try{
			//set up global variable for the destination screen
			Glob.setType(SearchType.DESTINATION);
			//if textfield is 0 or less than 0
			if(tfCode.getText().trim().length()<1){
				tfName.requestFocus();
				
			}
			else if(Integer.parseInt(tfCode.getText()) <= 0){
				JOptionPane.showMessageDialog(null, "Code must be a positive number");
				tfCode.setText("");
				tfCode.requestFocus();
				return;
			}
		//Select the row that will populate the screen
		NewTirDataBase a = (MyDestination) DatabaseExtension.getTableID("SELECT * FROM destination WHERE destinationID = '" + tfCode.getText() +"'")[0];
		//NewTirDataBase a = (MyAddressee) DatabaseExtension.getTableID("Select AddresseeID, addressee.name , address, postcode, town, province, addressee.countryID, country.name, phonenumber, fax, nif, contact, email from addressee, country where addressee.countryid = country.countryID and addresseeID = '" + tfCode.getText() +"'")[0];
		
		//System.out.println(((MyAddressee) a).getAddresseeID());
		//populating the fields
		tfName.setText(((MyDestination) a).getName());
		try{
			//System.out.println("This is the value of countryID in the addressee table " + String.valueOf(((MyAddressee) a).getCodeCountryID()));
			if(String.valueOf(((MyDestination) a).getCodeCountryID()).equals("null")){
				
				tfCountryCode.setText("");
				
			}else{
			tfCountryCode.setText(((MyDestination) a).getCodeCountryID());
			}
		
			}catch(Exception e){
				System.out.println("This is the exception regarding the country code");
				e.printStackTrace();
			}
		
		tfCountryName.setText(((MyDestination) a).getCountryName());
		//System.out.println("this is the Tax id and name" + c.getTaxID() + c.getTaxName());
		System.out.println("intro has been pressed");
		//requestfocus for the next field when pressing enter
		tfName.requestFocus();
		}catch(ArrayIndexOutOfBoundsException exception){
			System.out.println("This is the exception release when id not in database");
			//if there is no id in the database tfName set to empty
			//tfName.setText(null);
			exception.printStackTrace();
			//requestfocus for the next field when pressing enter
			tfName.requestFocus();
		}catch(NumberFormatException exception){
			JOptionPane.showMessageDialog(null, "Code must be a positive number");
			tfCode.setText(null);
			System.out.println("This is the exception release when there is an String");
			exception.printStackTrace();
		}catch(Exception exception){
			System.out.println("General Exception");
			exception.printStackTrace();
		}
	}
	
	public void initCountry(MyCountry country){
		
		tfCountryCode.setText(country.getCountryID());
		tfCountryName.setText(country.getCountryName());
		
	}

	// method needed to set focus from other screens
	public void setTextCodeFocus() {
		tfCode.requestFocus();
	}

	// reset fields
	public void resetFields() {
		tfCode.setText("");
		tfName.setText("");
		tfCountryCode.setText("");
		tfCountryName.setText("");
		tfCode.requestFocus();
	}

	// method needed to get value from text code in other screens
	public String getFieldCode() {
		return tfCode.getText();
	}
	
	public String getFieldCountry() {
		return tfCountryCode.getText();
	}

	// method for saving the object
	public void saveDialog() throws Exception{
		//Glob.type = SearchType.TAX;
		Glob.setDialog(DialogType.OVERWRITE);
		try{
		if(tfName.getText().trim().length()<1) {
			JOptionPane.showMessageDialog(null, "Name may not be empty");
			tfName.requestFocus();
			return;
		}
		
		if(!tfCode.getText().trim().isEmpty()) {
			
			if(Integer.parseInt(tfCode.getText())<1){
				JOptionPane.showMessageDialog(null, "Code has to be a valid number");
				tfCode.setText("");
				tfCode.requestFocus();
				return;
				
			}
			}
		ScreenHandling.checkIdOnTable(tfCountryCode, SearchType.COUNTRY);
		

		ArrayList<Integer> ids = DatabaseExtension.columnIDs("Select * from destination");
		//System.out.println(ids);
		boolean Ok = false;
		if(tfCode.getText().trim().length()<1) {
			//Do nothing
			}else{
				
		for (int i: ids) {
			if (i == Integer.parseInt(tfCode.getText()))
					Ok=true;
		}		
			if (Ok) {
			//JOptionPane.showMessageDialog(null, "This ID is not on the Tax table");
			Dialog d = Dialog.getInstance();
			d.setVisible(true);
			Destination.getInstance().disableDestination();
			return;
			
		}
			}
			if(Ok==false){
			save();			
			}
			
	}catch (NumberFormatException e){
		System.out.println("This is the general expetion inside saveDialog");
		JOptionPane.showMessageDialog(null, "Code must be a positive number");
		tfCode.setText("");
		tfCode.requestFocus();
		e.printStackTrace();
		return;
	}
	}

	// method that saves the object in the database
	public void save() {
		try {
			Glob.setType(SearchType.DESTINATION);
			String[] data = new String[3];
			try{
				data[0] = tfCode.getText();	
				}catch(Exception code){
					
					code.printStackTrace();
					
				}
				System.out.println("This is the id got from the tfcode inside save" + data[0]);
				if(data[0].isEmpty()){
				data[0] = null;
				}
			
				data[1] = tfName.getText();
				
				
			try{
				if(tfCountryCode.getText().isEmpty()){
					
					data[2] = null;
					
				}else{
					//System.out.println("The ELSE has happeneded");
					data[2] = tfCountryCode.getText();
				}

			}catch(Exception country){
				country.printStackTrace();
				JOptionPane.showMessageDialog(null, "Country must be a proper integer number");
			}
			System.out
					.println("this is the string of data from country in the method save"
							+ data[0] + data[1]);
			MyDestination destination = new MyDestination(data);
			
			DatabaseExtension.saveDestination(destination);
			resetFields();
			setTextCodeFocus();
		} catch (SQLException e) {
			JOptionPane.showMessageDialog(null, "Code must be a number");
			e.printStackTrace();
			tfCode.setText("");
			tfCode.requestFocus();
			return;
		} catch (NumberFormatException e) {
			JOptionPane.showMessageDialog(null, "Code must be a number");
			e.printStackTrace();
			tfCode.setText("");
			tfCode.requestFocus();
			return;
		} catch (Exception exception) {
			exception.printStackTrace();
		}
	}

	// method that calls the searchwindow
	public void search() {
		SearchWindow s = SearchWindow.getInstance();
		s.setTitle();
		s.setVisible(true);
		disableDestination();
	}

	// method to disable the screen
	public void disableDestination() {
		Destination.getInstance().disable();
		disable = true;
	}

	// method to enable the screen
	public void enableDestination() {
		Destination.getInstance().enable();
		disable = false;
		tfCode.requestFocus();
		Destination.getInstance().toFront();
	}

	// method to get the disable boolean
	public boolean getDisable() {
		return disable;
	}

	// method to close the screen
	public void escape() {
		Destination.getInstance().dispose();
		Menu.getInstance().enableMenu();
	}
}
